/**
 * Created by XianTao on 2016/7/24
 * <p/>
 * Copyright (c) 2015-2015
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 */
package org.smartspring.activiti.demo.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service
@Slf4j
public class ActivitiHystrixService {
    @Autowired
    private RestTemplate restTemplate;
    private String baseUrl = "http://localhost:8090";

//-----------------Deployment-------------------------------------

    /** List of Deployments */
    @HystrixCommand(fallbackMethod = "fallback")
    public String getRepositoryDeployments(){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/repository/deployments", String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    /** Get a deployment */
    @HystrixCommand(fallbackMethod = "fallback2")
    public String getRepositoryDeployment(String deploymentId){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/repository/deployments/" + deploymentId, String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    /** Create a new deployment */
    @HystrixCommand(fallbackMethod = "fallback")
    public String createRepositoryDeployments(){
        LinkedMultiValueMap<String, Object> param = new LinkedMultiValueMap<String, Object>();
        param.add("file", new ClassPathResource("processes/leave-dynamic-form/test.bpmn"));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(param, headers);

        ResponseEntity<String> stringResponseEntity = restTemplate.exchange(
                baseUrl + "/repository/deployments", HttpMethod.POST, requestEntity, String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    /** Delete a deployment */
    @HystrixCommand(fallbackMethod = "fallback2")
    public String deleteRepositoryDeployment(String deploymentId){
        restTemplate.delete(baseUrl + "/repository/deployments/" + deploymentId);
        log.info("delete a deployment: " + deploymentId);
        return "success";
    }

    /** List resources in a deployment */
    @HystrixCommand(fallbackMethod = "fallback2")
    public String getResourcesOfRepositoryDeployment(String deploymentId){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/repository/deployments/" + deploymentId + "/resources", String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    /** Get a deployment resource
     *
     * @param deploymentId
     * @param resourceId make sure to URL-encode
     * @return
     */
    @HystrixCommand(fallbackMethod = "fallback3")
    public String getResourceOfRepositoryDeployment(String deploymentId, String resourceId){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/v2/repository/deployments/" + deploymentId + "/resources/" + resourceId, String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    /** Get a deployment resource content
     *
     * @param deploymentId
     * @param resourceId make sure to URL-encode
     * @return
     */
    @HystrixCommand(fallbackMethod = "fallback3")
    public String getResourceDataOfRepositoryDeployment(String deploymentId, String resourceId){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/v2/repository/deployments/" + deploymentId + "/resourcedata/" + resourceId, String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

//-----------------Process Definitions-------------------------------------
    @HystrixCommand(fallbackMethod = "fallback")
    public String getRepositoryProcessDefinitions(){
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/repository/process-definitions", String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

    @HystrixCommand(fallbackMethod = "fallback2")
    public String getRepositoryProcessDefinition(String processDefinitionId) {
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(baseUrl + "/repository/process-definitions/" + processDefinitionId, String.class);
        log.info(stringResponseEntity.toString());
        String body = stringResponseEntity.getBody();
        log.info(body);
        return body;
    }

//-----------------回调--------------------------------------------------------------------

    public String fallback(Throwable e){
        e.printStackTrace();
        String message = "activiti模块故障";
        log.info(message);
        return message;
    }

    public String fallback2(String param, Throwable e){
        log.info("param: " + param);
        e.printStackTrace();
        String message = "activiti模块故障";
        log.info(message);
        return message;
    }

    public String fallback3(String param1, String param2, Throwable e){
        log.info("param1: " + param1);
        log.info("param2: " + param2);
        e.printStackTrace();
        String message = "activiti模块故障";
        log.info(message);
        return message;
    }
}
